﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace BaseTool
{

    /// <summary>
    /// 投影仪参数类
    /// </summary>
    [Serializable]
    public class ProjectorParam
    {
        /// <summary> 串口参数 </summary>
        public SerialPortParam serialPortParam = new SerialPortParam();
        /// <summary> 投影图像列表 </summary>
        public List<ProjectorImageMessage> proImageList = null;

        /// <summary> 标定时投影仪参数 </summary>
        public ProjectorConTrigger calibrationParam = new ProjectorConTrigger();
        /// <summary> 重建时投影仪参数 </summary>
        public ProjectorConTrigger reconstructParam = new ProjectorConTrigger();

        /// <summary>
        /// 重置图像列表
        /// </summary>
        public void ResetImageList()
        {
            //默认队列
            proImageList = new List<ProjectorImageMessage>();
            for (int i = 0; i <= 255; i++)
            {
                proImageList.Add(new ProjectorImageMessage((byte)i));
            }


            proImageList[23].DefaultText = "小十字架";
            proImageList[24].DefaultText = "大十字架改";
            proImageList[25].DefaultText = "全黑";
            proImageList[26].DefaultText = "散斑";
            proImageList[27].DefaultText = "三线大十字架";
            proImageList[28].DefaultText = "棋盘格";

            proImageList[23].Remark = "（内部图卡）不能修改";
            proImageList[24].Remark = "（内部图卡）不能修改";
            proImageList[25].Remark = "（内部图卡）不能修改";
            proImageList[26].Remark = "（内部图卡）不能修改";
            proImageList[27].Remark = "（内部图卡）不能修改";
            proImageList[28].Remark = "（内部图卡）不能修改";
        }
    }

    /// <summary>
    /// 串口参数类
    /// </summary>
    [Serializable]
    public class SerialPortParam
    {
        /// <summary> 通信端口 </summary>
        public string PortName = "";
        /// <summary> 波特率 </summary>
        public int BaudRate = 115200;
        /// <summary> 每个字节的位数 </summary>
        public int DataBits = 8;
        /// <summary> 奇偶校验位 </summary>
        public Parity Parity = Parity.None;
        /// <summary> 停止位 </summary>
        public StopBits StopBits = StopBits.One;
        /// <summary> 发送延时 </summary>
        public int SendDelayTime = 50;

        /// <summary> 波特率 </summary>
        [NonSerialized, XmlIgnore]
        public string[] ConstBaudRate = new string[14] {
            "1200","2400","4800","9600","14400","19200","43000","56000","57600","115200", "128000", "230400", "256000", "460800"};
        /// <summary> 数据位 </summary>
        [NonSerialized, XmlIgnore]
        public string[] ConstDataBit = new string[] {
            "5bit", "6bit", "7bit", "8bit"};

    }

    /// <summary>
    /// 投影仪触发帧率计算工具
    /// </summary>
    [Serializable]
    public class ProjectorFrame
    {
        /// <summary> 
        /// 传入投影仪参数
        ///     *范围01-255，01最快，255最慢，00不确定  
        ///     *01为120帧/秒，120为1帧/秒，255为0.47帧/秒
        /// </summary>
        public byte Data = 120;

        /// <summary>
        /// 投影仪频率（Hz） / 每秒多少张图
        /// </summary>
        public double Frequency
        {
            get
            {
                if (Data == 0)
                    return -1;
                return 120.0 / Data;
            }
        }

        /// <summary>
        /// 曝光时间（ms）
        /// </summary>
        public double ExposureTime_ms
        {
            get
            {
                if (Data == 0)
                    return -1;
                return 1000.0 * Data / 120;
            }
        }
        /// <summary>
        /// 曝光时间（us）
        /// </summary>
        public double ExposureTime_us
        {
            get
            {
                if (Data == 0)
                    return -1;
                return 1000.0 * 1000.0 * Data / 120;
            }
        }

        public ProjectorFrame() { }
        public ProjectorFrame(byte data) { Data = data; }
        public ProjectorFrame(int data) { Data = (byte)data; }
    }

    /// <summary>
    /// 写入图像信息
    /// </summary>
    [Serializable]
    public class ProjectorImageMessage
    {
        /// <summary> 索引 </summary>
        public byte Index = 0;
        /// <summary> 索引（16进制） </summary>
        public string IndexHex { get { return Index.ToString("X2"); } }

        /// <summary> 图像数据 </summary>
        public byte[] ImageData = new byte[0];
        /// <summary> 图像数据是否为空 </summary>
        public bool ImageIsEmpty { get { return ImageData == null || ImageData.Length == 0; } }
        /// <summary> 图像高度 </summary>
        public int ImageHeight = 0;
        /// <summary> 图像宽度 </summary>
        public int ImageWidth = 0;

        /// <summary> 默认图像信息 </summary>
        public string DefaultText = string.Empty;
        /// <summary> 备注 </summary>
        public string Remark = string.Empty;

        /// <summary>
        /// 写入图像信息
        /// </summary>
        public ProjectorImageMessage() { }
        /// <summary>
        /// 写入图像信息
        /// </summary>
        /// <param name="index">索引</param>
        public ProjectorImageMessage(byte index)
        {
            Index = index;
        }
        /// <summary>
        /// 写入图像信息
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="defaultText">默认信息</param>
        public ProjectorImageMessage(byte index, string defaultText)
        {
            Index = index;
            DefaultText = defaultText;
        }
    }

    /// <summary>
    /// 投影仪连续触发参数
    /// </summary>
    [Serializable]
    public class ProjectorConTrigger
    {
        /// <summary> 开始图卡编号 </summary>
        public byte Start;
        /// <summary> 帧率 </summary>
        public ProjectorFrame Frame;
        /// <summary> 图片数量 </summary>
        public byte Count;

        /// <summary>
        /// 返回图像索引信息
        /// </summary>
        public string GetImageIndex
        {
            get
            {
                if (Count <= 0)
                    return $"null";
                else if (Count == 1)
                    return $"0x{Start.ToString("X2")}";
                else
                    return $"0x{Start.ToString("X2")} - 0x{(Start + Count - 1).ToString("X2")}";
            }
        }
    }
}
